using System;
using System.Collections.Generic;
using System.Data.Linq;
using System.Data.Linq.Mapping;
using System.Linq;
using System.Reflection;

namespace Magiq.Sql {
  public class TableMapping {
    private readonly DataContext dataContext;

    private MetaDataMember discriminator;
    private IEnumerable<MetaDataMember> persistentDataMembers;

    public TableMapping(Type type, DataContext dataContext) {
      Type = type;
      this.dataContext = dataContext;
    }

    public bool IsEntity {
      get { return MetaType.IsEntity; }
    }

    public string TableName {
      get { return dataContext.TableNameFor(Type); }
    }

    private IEnumerable<MetaDataMember> PersistentDataMembers {
      get {
        if (persistentDataMembers == null)
          persistentDataMembers = MetaType.DataMembers;

        return persistentDataMembers;
      }
    }

    private MetaType MetaType {
      get { return dataContext.Mapping.GetMetaType(Type); }
    }

    public PropertyInfo DiscriminatorProperty {
      get { return (PropertyInfo) Discriminator.Member; }
    }

    public bool IsInheritance {
      get { return Discriminator != null; }
    }


    private MetaDataMember Discriminator {
      get {
        if (discriminator == null)
          discriminator = MetaType.Discriminator;
        return discriminator;
      }
    }

    public object DiscriminatorCode {
      get { return MetaType.InheritanceCode; }
    }

    public IEnumerable<MetaDataMember> IdentityMembers {
      get { return MetaType.IdentityMembers; }
    }

    public Type Type { get; private set; }

    public IEnumerable<string> ColumnsFor(string propertyName) {
      var dataMember = PersistentDataMembers.Single(x => x.Name == propertyName);

      return dataMember.IsAssociation
               ? dataMember.Association.ThisKey.Select(x => x.MappedName)
               : new[] {dataMember.MappedName};
    }

    public string ColumnFor(string propertyName) {
      return ColumnsFor(propertyName).FirstOrDefault();
    }
  }
}